# 需要使用正则表达式，导入re模块
import re
# 导入网络请求模块
import requests
# 导入os模块，用于获取路径
import os
# 导入json模块，用于数据处理
import json

data = []                   # 用于存储整理好的车次信息
station_name_list = []      # 保存起售车站名称列表
station_time_list = []      # 保存起售车站对应时间列表
today_ticket_list = []      # 保存今天列车信息，已经处理是否有票
three_ticket_list = []      # 保存三天列车信息，已经处理是否有票
five_ticket_list = []       # 保存五天列车信息，已经处理是否有票
today_list = []             # 保存今天列车信息，未处理
three_list = []             # 保存三天列车信息，未处理是否有票
five_list = []              # 保存五天列车信息，未处理是否有票

# 获取余票信息
def get_tickets(from_station_name, from_station, to_station_name, to_station, date, back_date):
    print("$$$$$$$$$ get_tickets $$$$$$$$$")
    print(from_station_name, from_station, to_station_name, to_station, date, back_date)
    # 获取余票信息的请求地址
    url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}' \
          '&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}' \
          '&purpose_codes=ADULT'.format(date, from_station, to_station)
    print(url)
    # 头部信息，欺骗服务器
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/76.0.3809.132 Safari/537.36"}
    # 获取cookie
    from_station_name = from_station_name.encode('utf-8')
    to_station_name = to_station_name.encode('utf-8')
    post_data = {'back_train_date': back_date,
                 '_json_att': "", 'flag': 'dc',
                 'leftTicketDTO.from_station': from_station,
                 'leftTicketDTO.to_station': to_station,
                 'leftTicketDTO.from_station_name': from_station_name,
                 'leftTicketDTO.to_station_name': to_station_name,
                 'leftTicketDTO.train_date': date,
                 'pre_step_flag': 'index',
                 'purpose_code': 'ADULT'}
    init_url = 'https://kyfw.12306.cn/otn/leftTicket/init'      # 获取cookie请求地址
    init_resp = requests.post(init_url, data=post_data, headers=header, allow_redirects=True, verify=False)
    cookies = init_resp.cookies
    from_station_name = from_station_name.decode("latin1")
    to_station_name = to_station_name.decode("latin1")

    cookies.set('_jc_save_fromStation', from_station_name + ',' + from_station, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_toStation', to_station_name + ',' + to_station, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_fromDate', date, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_toDate', back_date, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_wfdc_flag', 'dc', domain='kyfw.12306.cn', path='/')

    # 发送请求信息
    response = requests.get(url=url, headers=header, cookies=cookies)

    # 将JSON数据转换成为字典类型，通过键值对取数据
    result = response.json()    # 转换成字典
    result = result.get('data').get('result')  # 取数据 json数据里面包含 data 与 result
    print(result)
    # 判断车站信息文件是否存在
    if is_stations("stations_name.text"):
        stations_name = eval(read("stations_name.text"))  # 读取所有车站的名字并转换为字典
        if len(result) != 0:
            data.clear()
            # 分割数据到列表中
            for info in result:
                ticket_info_list = info.split('|')
                # print("ticket_info_list = {}".format(ticket_info_list))
                # 查找对应车站的名称
                from_station = list(stations_name.keys())[list(stations_name.values()).index(ticket_info_list[6])]
                to_station = list(stations_name.keys())[list(stations_name.values()).index(ticket_info_list[7])]
                # 创建座位数组，由于返回的数据中含有空值，所以将空改成"--"便于识别
                seat = [ticket_info_list[3], from_station, to_station, ticket_info_list[8], ticket_info_list[9],
                        ticket_info_list[10], ticket_info_list[32], ticket_info_list[31], ticket_info_list[30],
                        ticket_info_list[21], ticket_info_list[23], ticket_info_list[33], ticket_info_list[28],
                        ticket_info_list[24], ticket_info_list[29], ticket_info_list[26]]
                print("seat = {}".format(seat))
                newSeat = []
                # 循环将座位信息中的空值改成“--”
                for s in seat:
                    if s == "":
                        s = '--'
                    else:
                        s = s
                    newSeat.append(s)  # 保存新的座位信息
                data.append(newSeat)
        # print(data)
        return data  # 返回整理好的车次信息


# 获取车站名称与英文名
def get_stations_name():
    # 模拟发送请求，获取所有车站名称，通过输入的站名称转化查询地址的参数
    # 通过网页信息得到的站名及英文对应的请求地址
    url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9112"

    # 发送请求
    response = requests.get(url, verify=True)

    # 获取所需要的车站名称
    # \u4e00 unicode编码中文的开始字符 \u9fa5  unicode编码中文的结束字符
    # 后面的+代表至少出现一次
    stations = re.findall('([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)     # 通过正则表达式来找到对应的车站信息
    stations = dict(stations)
    stations = str(stations)
    write(stations, 'stations_name.text')


# 获取起售时间
def get_selling_time(station_name):
    print(station_name)
    station_name_list.clear()
    station_time_list.clear()
    stations = eval(read('stations_selling_time.text'))     # 读取所有车站并转换为字典类型
    # 头部信息，欺骗服务器
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/76.0.3809.132 Safari/537.36"}
    '''
    init_url = 'https://www.12306.cn/index/otn/zwdch/queryCC'
    post_data = {
        'train_station_code': ''
    }
    print("获取cookie")
    init_resp = requests.post(init_url, data=post_data, headers=header, verify=True)
    print("状态码1： {}".format(init_resp.status_code))
    cookies = init_resp.cookies
    print("cookies = {}".format(cookies))
    '''
    url = 'https://www.12306.cn/index/otn/index12306/queryScSname'
    # 表单参数
    form_data = {
        "station_telecode": station_name}

    print("form_data = {}".format(form_data))
    print("请求post。。。。")
    response = requests.post(url, data=form_data, verify=True)
    response.encoding = 'utf-8'     # 对返回的数据进行编码
    print("状态码2： {}".format(response.status_code))
    print(response.text)
    json_data = response.json()                      # 解析json数据
    json_data = json_data.get('data')                # 获取json中的数据
    print("data = {}".format(json_data))
    for na in json_data:
        if na in stations:
            station_name_list.append(na)
    print("name = {}".format(station_name_list))
    for na in station_name_list:
        time = stations.get(na)
        station_time_list.append(time)
    print("time = {}".format(station_time_list))
    return station_name_list, station_time_list


# 查询卧铺售票分析数据
def get_sleeper_ticket(from_station_name, from_station, to_station_name, to_station, date, back_date, which_day):
    sleep = get_tickets(from_station_name, from_station, to_station_name, to_station, date, back_date)
    print("sleep = {}".format(sleep))
    for info in sleep:
        sleeper_ticket = [info[0], info[1], info[2], info[3], info[4], info[5], info[9], info[10], info[12]]
        print("sleeper_ticket = {}".format(sleeper_ticket))
        if which_day == 1:
            # 将高铁、动、C开头的车次，排除
            if sleeper_ticket[0].startswith('G') == False and sleeper_ticket[0].startswith('D') == False \
                    and sleeper_ticket[0].startswith('C') == False:
                today_list.append(sleeper_ticket)  # 将高级软卧、软卧、硬卧未处理信息添加至列表中
                new_seat = is_ticket(sleeper_ticket, from_station, to_station)  # 判断某车次是否有票
                today_ticket_list.append(new_seat)  # 将判断后的车次信息添加至对应的列表当中
        elif which_day == 3:  # 判断三天的车次信息
            # 将高铁、动、C开头的车次，排除
            if sleeper_ticket[0].startswith('G') == False and sleeper_ticket[0].startswith('D') == False \
                    and sleeper_ticket[0].startswith('C') == False:
                three_list.append(sleeper_ticket)  # 将高级软卧、软卧、硬卧未处理信息添加至列表中
                new_seat = is_ticket(sleeper_ticket, from_station, to_station)  # 判断某车次是否有票
                three_ticket_list.append(new_seat)  # 将判断后的车次信息添加至对应的列表当中
        elif which_day == 5:  # 判断五天的车次信息
            # 将高铁、动、C开头的车次，排除
            if sleeper_ticket[0].startswith('G') == False and sleeper_ticket[0].startswith('D') == False \
                    and sleeper_ticket[0].startswith('C') == False:
                five_list.append(sleeper_ticket)  # 将高级软卧、软卧、硬卧未处理信息添加至列表中
                new_seat = is_ticket(sleeper_ticket, from_station, to_station)  # 判断某车次是否有票
                five_ticket_list.append(new_seat)  # 将判断后的车次信息添加至对应的列表当中


# 判断高级软卧、软卧、硬卧是否有票
def is_ticket(sleeper_ticket, from_station, to_station):
    # 判断高级软卧、软卧、硬卧任何一个有票的话，就说明该趟类车有卧铺车票
    if sleeper_ticket[6] == '有' or sleeper_ticket[7] == '有' or sleeper_ticket[8] == '有':
        tmp_tem = '有'
    else:
        # 判断高级软卧、软卧、硬卧对应的如果是数字说明也有票，其它为无票
        if sleeper_ticket[6].isdigit() or sleeper_ticket[7].isdigit() or sleeper_ticket[8].isdigit():
            tmp_tem = '有'
        else:
            tmp_tem = '无'
    # 创建新的座位列表，显示某趟列车是否有卧铺票
    new_seat = [sleeper_ticket[0], from_station, to_station, sleeper_ticket[3],
                sleeper_ticket[4], sleeper_ticket[5], tmp_tem]
    return new_seat     # 返回该列表



# 获取车站起售信息
def get_stations_selling_time():
    url = "https://www.12306.cn/index/script/core/common/qss_v10040.js"
    # 发送请求
    response = requests.get(url, verify=True)
    json_str = re.findall('{[^}]+}', response.text)     # 匹配括号内所有内容
    print(json_str)
    time_js = json.loads(json_str[0])                    # 解析json数据
    print(time_js)
    print(str(time_js))
    write(str(time_js), 'stations_selling_time.text')


def write(stations, file_name):
    file = open(file_name, 'w', encoding='utf-8')   # 以写模式打开文件
    file.write(stations)                            # 写入数据
    file.close()


def read(file_name):
    file = open(file_name, 'r', encoding='utf-8')   # 以读的模式打开文件
    data = file.readline()                          # 读取数据
    file.close()
    return data


def is_stations(file_name):
    is_station = os.path.exists(file_name)     # 判断文件是否存在
    return is_station

